package mop.model;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

/**
 * Abstract Model Class
 * in the name of Pull Up refactoring
 * 
 * @author MOP Team 7
 * 
 * @invar 	ID is valid.
 */

public abstract class AbstractModel implements ModelInterface
{

	/**
	 * Default Constructor
	 * 
	 * @post set propertyChangeSupport
	 */
	protected AbstractModel()
	{
		this.propertyChangeSupport = new PropertyChangeSupport(this);
	}

	/***************************************************************************
	 * 						Model interface
	 ***************************************************************************/
	
	/**
	 * @see ModelInterface#getId()
	 */
	public abstract String getId(); 
	
	/**
	 * get a reference to the interface
	 */
	public abstract ModelInterface getInterface();
	
	
	/***************************************************************************
	 * 						Object interface
	 ***************************************************************************/
	
	/**
	 * to String function -- used for comparison reasons
	 * 
	 * @return description
	 */
	public String toString()
	{
		return this.getId();
	}
	
	/**
	 * Check whether given object is same as this object
	 * Yes, we use instanceof (NOOOOOOOOOOOOOOO!), but otherwise madame Lizkov would complain.
	 * 
	 * @return true if two objects have the same description and id
	 */
	public boolean equals(Object obj)
	{
		if(!(obj instanceof ModelInterface))
			throw new IllegalArgumentException("Given object must implement modelinterface");
		
		return (this.toString().equals(obj.toString())) && (this.getId().equals(((ModelInterface) obj).getId())) ;
		
	}
	
	/***************************************************************************
	 * 						Property change support
	 ***************************************************************************/
	
	/**
	 * @see 	ModelInterface#addPropertyChangeListener(PropertyChangeListener)
	 * @effect 	Listener added
	 * 			| propertyChangeSupport.addPropertyChangeListener(listener)
	 */
	public void addPropertyChangeListener(PropertyChangeListener listener)
	{
		propertyChangeSupport.addPropertyChangeListener(listener);
	}

	/**
	 * @see 	ModelInterface#removePropertyChangeListener(PropertyChangeListener)
	 * @effect 	Listener removed
	 * 			| propertyChangeSupport.removePropertyChangeListener(listener)
	 */
	public void removePropertyChangeListener(PropertyChangeListener listener)
	{
		propertyChangeSupport.removePropertyChangeListener(listener);
	}
        
        protected void firePropertyChange(String propertyName, Object oldValue, Object newValue)
        {
            propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
        }
	
	/**
	 * Property change support instance
	 */
	protected final PropertyChangeSupport propertyChangeSupport;

}
